package com.keycloak.admin.config;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLEncoder;
import java.net.UnknownHostException;

/*
*  小程序支付使用
* */
public class QiFanxWxConfig implements WXPayConfig {
    private byte[] certData;
    private static Logger logger = LogManager.getLogger(QiFanxWxConfig.class);

    private static QiFanxWxConfig factory = new QiFanxWxConfig();



    public static QiFanxWxConfig getFactory() {
        return factory;
    }

    //小程序支付/登陆用
    @Override
    public String getAppID() {
        //return "wx51acf05a386eb54f";
        //return "wx33dba27dca71e6c0"; //悦道出行
        return "wx055a3d2d04ea16a3";//悦道用车
    }


    //小程序支付用
    @Override
    public String getKey() {
        //return "aeb9ff4eee94f9b07f11c4451c3eea6a";
        //return "8fc0bd11a997a1ff98be058e145bb83a";
        //return "6c387a2779aeebba355a6a3cfc2f85d6";
        return "uaQnXaoWeiXinZinYue10D1220hiFu27"; //悦道用车
    }

    //登陆用（微信授权小程序登陆）
    public String getAppSecret() {
        //return "f3170bfda2465516458e81145548277e"; //悦道出行
        return  "22980626633b691a5a26b289bd6da2b0";//悦道用车
    }



    @Override
    public String getMchID() {
        //return "1484229362";
        //return "1227962902";
        return "1502479061";
    }



	@Override
	public InputStream getCertStream() {
		ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    public void setCertStream(ServletContext context) {
        if (this.certData != null && this.certData.length > 0) {
            //already loaded
            return;
        }
        try {
            String certPath = context.getRealPath("/") + "WEB-INF/apiclient_cert.p12";
            File file = new File(certPath);
            InputStream certStream = new FileInputStream(file);
            this.certData = new byte[(int) file.length()];
            certStream.read(this.certData);
            certStream.close();
        } catch (Exception e) {
            logger.error("setCertStream error:" + e.getMessage());
        }
    }

    @Override
    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    @Override
    public int getHttpReadTimeoutMs() {
        return 10000;
    }

    public String getIP() {
        String ip = "";
        InetAddress addr;
        try {
            addr = InetAddress.getLocalHost();
            ip = addr.getHostAddress();//获得本机IP
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        return ip;
    }

    public String getNofigyUrl() {
        //return "http://www.gugensoft.com/WxPay/SuccessNotifyX";//异步通知地址
        return "https://ydx.yuedaowang.com/WxAppPay/XWXSuccessNotifyX";
    }

    public String getWxAppPayNofigyUrl() {
        //return "http://www.gugensoft.com/WxPay/SuccessNotifyX";//异步通知地址
        return "http://dev.yuedaowang.com/auth/WxAppPay/SuccessNotifyX";
    }


    public String getAccessToken(ServletContext application) {
        try {
            String access_token = (String) application.getAttribute("access_token");
            String refresh_token = (String) application.getAttribute("refresh_token");
            Object tokenExpire = application.getAttribute("expires_in");
            boolean isExpire = false;
            long currentTime = System.currentTimeMillis();
            if (tokenExpire == null || (tokenExpire != null && (long) tokenExpire < currentTime)) {
                isExpire = true;
            }
            if (access_token == null || (refresh_token == null && access_token != null && isExpire)) {
                //获取access_token
                //https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
                String tokenURL = "https://api.weixin.qq.com/cgi-bin/token";
                String query = String.format(
                        "grant_type=client_credential&appid=%s&secret=%s",
                        URLEncoder.encode(this.getAppID(), "UTF-8"),
                        URLEncoder.encode(this.getKey(), "UTF-8"));

                URL url = new URL(tokenURL + "?" + query);

                InputStream is = url.openStream();
                JsonReader rdr = Json.createReader(is);
                JsonObject obj = rdr.readObject();
                rdr.close();

                logger.info("get new access_token result:" + obj.toString());

                if (obj.containsKey("errcode")) {
                    String errcode = obj.getString("errcode");
                    String errmsg = obj.getString("errmsg");
                    logger.error("getAccessToken error:" + errcode + "," + errmsg);
                    return null;
                } else {
                    String token = obj.getString("access_token");
                    int expires_in = obj.getInt("expires_in");
                    application.setAttribute("access_token", token);
                    application.setAttribute("expires_in", expires_in * 1000 + System.currentTimeMillis());
                    return token;
                }
            } else if (refresh_token != null && isExpire) {
                //try refresh token first,TODO: check 30 days since last get
                //https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
                String tokenURL = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
                String query = String.format(
                        "grant_type=refresh_token&appid=%s&refresh_token=%s",
                        URLEncoder.encode(this.getAppID(), "UTF-8"),
                        URLEncoder.encode(refresh_token, "UTF-8"));

                URL url = new URL(tokenURL + "?" + query);

                InputStream is = url.openStream();
                JsonReader rdr = Json.createReader(is);
                JsonObject obj = rdr.readObject();
                rdr.close();

                logger.info("get new refresh_token result:" + obj.toString());

                if (obj.containsKey("errcode")) {
                    String errcode = obj.getString("errcode");
                    String errmsg = obj.getString("errmsg");
                    logger.error("get refresh_token error:" + errcode + "," + errmsg);
                    return null;
                } else {
                    String token = obj.getString("access_token");
                    String refresh = obj.getString("refresh_token");
                    int expires_in = obj.getInt("expires_in");
                    application.setAttribute("access_token", token);
                    application.setAttribute("refresh_token", refresh);
                    application.setAttribute("expires_in", expires_in * 1000 + System.currentTimeMillis());
                    return token;
                }
            } else {
                logger.info("access_token is still valid:" + access_token);
                return access_token;
            }
        } catch (Exception e) {
            logger.error("getAccessToken exception:" + e.getMessage());
        }
        return null;
    }

    //这个是微信回掉时使用的方法，没有用户session
    public String getUnionID(ServletContext application, String openid) {
        //获取用户基本信息（包括UnionID机制）
        //http请求方式: GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
        try {
            String access_token = this.getAccessToken(application);

            String tokenURL = "https://api.weixin.qq.com/cgi-bin/user/info";
            String query = String.format(
                    "access_token=%s&openid=%s&lang=zh_CN",
                    URLEncoder.encode(access_token, "UTF-8"),
                    URLEncoder.encode(openid, "UTF-8"));

            URL url = new URL(tokenURL + "?" + query);

            InputStream is = url.openStream();
            JsonReader rdr = Json.createReader(is);
            JsonObject obj = rdr.readObject();
            rdr.close();

            logger.info("get user info result:" + obj.toString());

            if (obj.containsKey("errcode")) {
                String errcode = obj.getString("errcode");
                String errmsg = obj.getString("errmsg");
                logger.error("getUnionID error:" + errcode + "," + errmsg);
                return openid;
            } else {
                String unionid = obj.getString("unionid");
                return unionid;
            }
        } catch (Exception e) {
            logger.error("getUnionID exception:" + e.getMessage());
        }
        return null;
    }

    public void getUserInfo(HttpSession session, String access_token, String openid) {
        try {
            // 获取用户基本信息（包括UnionID机制）
            String userinfoUrl = "https://api.weixin.qq.com/sns/userinfo";
            String userinfoquery = String.format(
                    "access_token=%s&openid=%s&lang=zh_CN",
                    URLEncoder.encode(access_token, "UTF-8"),
                    URLEncoder.encode(openid, "UTF-8"));

            URL fullurl = new URL(userinfoUrl + "?" + userinfoquery);

            InputStream isUI = fullurl.openStream();
            JsonReader rdrUI = Json.createReader(isUI);
            JsonObject objUI = rdrUI.readObject();
            rdrUI.close();

            logger.info("user info:" + objUI.toString());

            if (objUI.containsKey("errcode")) {
                String errcode = objUI.getString("errcode");
                String errmsg = objUI.getString("errmsg");
                logger.error("getUserInfo error:" + errcode + "," + errmsg);
            } else {
                if (objUI.containsKey("nickname")) {
                    String nickname = objUI.getString("nickname");
                    String headimgurl = objUI.getString("headimgurl");
                    session.setAttribute("nickname", nickname);
                    session.setAttribute("headimgurl", headimgurl);
                }
            }
        } catch (Exception e) {
            logger.error("getUserInfo exception:" + e.getMessage());
        }
    }
}
